package models

import (
	"errors"
	"github.com/jinzhu/gorm"
	"go.uber.org/zap"
)

type Article struct {
	Model

	TagID int `json:"tag_id" gorm:"index"`
	Tag   Tag `json:"tag"`

	Title      string `json:"title"`
	Desc       string `json:"desc"`
	Content    string `json:"content"`
	CreatedBy  string `json:"created_by"`
	ModifiedBy string `json:"modified_by"`
	State      int    `json:"state"`
}

func ExistArticleByID(id int) (bool, error) {
	var article Article
	err := db.Select("id").Where("id = ? AND deleted_on = ?", id, 0).First(&article).Error
	if err != nil {
		return false, err
	}
	if article.ID > 0 {
		return true, nil
	}
	return false, nil
}

func GetArticleTotal(maps interface{}) (int, error) {
	var count int
	err := db.Model(&Article{}).Where(maps).Count(&count).Error
	if err != nil {
		zap.L().Info("获取文章总数失败", zap.Error(err))
		return 0, err
	}
	return count, nil
}

func GetArticles(pageNum int, pageSize int, maps interface{}) ([]*Article, error) {
	var articles []*Article
	err := db.Preload("Tag").Where(maps).Offset(pageNum).Limit(pageSize).Find(&articles).Error
	if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
		zap.L().Info("获取文章不存在", zap.Error(err), zap.Int("pageNum", pageNum), zap.Int("pageSize", pageSize), zap.Any("maps", maps))
		return nil, err
	}
	return articles, nil
}

func GetArticle(id int) (*Article, error) {
	var article Article
	err := db.Where("id = ? AND deleted_on = ?", id, 0).First(&article).Error
	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
		zap.L().Info("model", zap.Int("该ID对应的文章不存在", id))
		return nil, err
	}
	// 这行可以查询到tag对象的值并放入到article中的tag字段内
	err = db.Model(&article).Related(&article.Tag).Error
	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
		zap.L().Info("model", zap.Int("该ID对应的tag不存在", id))
		return nil, err
	}
	return &article, err
}

func EditArticle(id int, data interface{}) error {
	if err := db.Model(&Article{}).Where("id = ? AND deleted_on = ?", id, 0).Updates(data).Error; err != nil {
		zap.L().Info("编辑文章失败", zap.Error(err))
		return err
	}
	return nil
}

func AddArticle(data map[string]interface{}) error {
	if err := db.Create(&Article{
		TagID:     data["tag_id"].(int),
		Title:     data["title"].(string),
		Desc:      data["desc"].(string),
		Content:   data["content"].(string),
		CreatedBy: data["created_by"].(string),
		State:     data["state"].(int),
	}).Error; err != nil {
		zap.L().Info("创建文章失败", zap.Error(err))
		return err
	}

	return nil
}

func DeleteArticle(id int) error {
	if err := db.Where("id = ?", id).Delete(Article{}).Error; err != nil {
		zap.L().Info("删除文章失败", zap.Error(err))
		return err
	}

	return nil
}

// BeforeCreate 新增添加时间戳
//func (article *Article) BeforeCreate(scope *gorm.Scope) error {
//	err := scope.SetColumn("CreatedOn", time.Now().Unix())
//	if err != nil {
//		zap.L().Error("article BeforeCreate callback error", zap.Error(err))
//	}
//
//	return nil
//}

// BeforeUpdate 修改添加时间戳
//func (article *Article) BeforeUpdate(scope *gorm.Scope) error {
//	err := scope.SetColumn("ModifiedOn", time.Now().Unix())
//	if err != nil {
//		zap.L().Error("article BeforeUpdate callback error", zap.Error(err))
//	}
//
//	return nil
//}

// CleanAllArticle 硬删除代码
func CleanAllArticle() (bool, error) {
	if err := db.Unscoped().Where("deleted_on != ? ", 0).Delete(&Article{}).Error; err != nil {
		return false, err
	}
	return true, nil
}
